package it.controllocredito.backend.phone;

import it.controllocredito.backend.Singleton;
import it.controllocredito.backend.persistence.DatabaseHandler;
import it.controllocredito.backend.persistence.bean.RegistroChiamate;
import it.controllocredito.backend.persistence.tables.RegistroChiamateTable;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import android.content.Context;
import android.provider.CallLog;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;

/**
 * TODO: trovare il modo di capire quando la telefonata � ricevuta o effettuata
 * 
 * @author Event
 * 
 */
public class CustomPhoneStateListener extends PhoneStateListener
{
	
	private static final String	log_class_name	= "CustomPhoneStateListener";
	
	private int					prevState;
	
	private String				stateString;
	
	private Context				context;
	
	public CustomPhoneStateListener(Context context)
	{
		super();
		Log.d(log_class_name, "- CustomPhoneStateListener created");
		this.prevState = -1;
		this.stateString = "Primo avvio";
		this.context = context;
	}
	
	@Override
	public void onCallStateChanged(int state, String incomingNumber)
	{
		
		switch (state)
		{
		case TelephonyManager.CALL_STATE_IDLE:
			this.callHandler(TelephonyManager.CALL_STATE_IDLE,
					new Date().getTime(), incomingNumber);
		break;
		case TelephonyManager.CALL_STATE_RINGING:
			this.callHandler(TelephonyManager.CALL_STATE_RINGING,
					new Date().getTime(), incomingNumber);
		break;
		case TelephonyManager.CALL_STATE_OFFHOOK:
			this.callHandler(TelephonyManager.CALL_STATE_OFFHOOK,
					new Date().getTime(), incomingNumber);
		break;
		}
	}
	
	private void callHandler(int state, long time, String incomingNumber)
	{
		Log.d(log_class_name,
				this.getStateString(prevState) + " -> "
						+ this.getStateString(state));
		boolean needToLog = false;
		
		if ((state == TelephonyManager.CALL_STATE_OFFHOOK)
				&& ((prevState == TelephonyManager.CALL_STATE_IDLE) || (prevState == -1)))
		{
			needToLog = true;
			stateString = "Inizio telefonata in uscita (" + incomingNumber
					+ ") [HOOK]";
		}
		
		if ((prevState == TelephonyManager.CALL_STATE_RINGING)
				&& (state == TelephonyManager.CALL_STATE_OFFHOOK))
		{
			needToLog = true;
			stateString = "Telefonata in corso... [HOOK]";
		}
		
		if ((prevState == TelephonyManager.CALL_STATE_OFFHOOK)
				&& (state == TelephonyManager.CALL_STATE_IDLE))
		{
			needToLog = true;
			stateString = "Fine telefonata [HOOK]";
		}
		
		if ((state == TelephonyManager.CALL_STATE_RINGING)
				&& ((prevState == TelephonyManager.CALL_STATE_IDLE) || (prevState == -1)))
		{
			needToLog = true;
			stateString = "Inizio telefonata in ingresso (" + incomingNumber
					+ ") [RING]";
		}
		
		if ((prevState == TelephonyManager.CALL_STATE_OFFHOOK)
				&& (state == TelephonyManager.CALL_STATE_IDLE))
		{
			needToLog = true;
			stateString = "Fine telefonata [RING]";
			
			String numeroTelefono;
			RegistroChiamate registroChiamate;
			
			Singleton.getInstance().getManagerCallLogHandler(context).aggiornaRegistroChiamate(null);
			ArrayList<RegistroChiamate> chiamate = Singleton.getInstance().getManagerCallLogHandler(context).aggiornaRegistroChiamate(null);
			if (chiamate != null && chiamate.size() > 0)
			{
				registroChiamate = chiamate.get(0);
				
				numeroTelefono = registroChiamate.getPrefissoTel() + registroChiamate.getNumeroTel();
				
				// TipoChiamata: 1. incoming, 2. outgoing, 3. missed
				long consumo = 0;
				if (registroChiamate.getTipo() != CallLog.Calls.MISSED_TYPE)
				{
					consumo = registroChiamate.getDurata();
				}
				
//				testato da emulatore, funziona ma non aggancia la prima telefonata. aggancia solo dalla seconda in poi
				GregorianCalendar data = new GregorianCalendar();
				DatabaseHandler databaseHandler = new DatabaseHandler(context);
				
				databaseHandler.addRecord(RegistroChiamateTable.getName(),
						RegistroChiamateTable.createRecord(
								registroChiamate.getAnno(),
								registroChiamate.getMese(),
								registroChiamate.getGiorno(),
								registroChiamate.getGiornoSettimana(),
								registroChiamate.getOra(),
								registroChiamate.getTipo(),
								registroChiamate.getDurata(), "",
								registroChiamate.getNumeroTel()));
				
				Toast.makeText(context,
						"Ho intercettato la chiamata.. " + stateString,
						Toast.LENGTH_LONG).show();
			}
			
		}
		
		if ((prevState == TelephonyManager.CALL_STATE_IDLE)
				&& (state == TelephonyManager.CALL_STATE_IDLE))
		{
			needToLog = false;
		}
		
		if ((prevState == TelephonyManager.CALL_STATE_OFFHOOK)
				&& (state == TelephonyManager.CALL_STATE_OFFHOOK))
		{
			needToLog = false;
		}
		
		if (needToLog)
		{
			Log.i(log_class_name, stateString);
			prevState = state;
		}
		
	}
	
	private String getStateString(int state)
	{
		String stateString = "";
		
		switch (state)
		{
		case -1:
			stateString = "INIT";
		break;
		case TelephonyManager.CALL_STATE_IDLE:
			stateString = "IDLE";
		break;
		case TelephonyManager.CALL_STATE_RINGING:
			stateString = "RING";
		break;
		case TelephonyManager.CALL_STATE_OFFHOOK:
			stateString = "HOOK";
		break;
		}
		
		return stateString;
	}
}